
import time
import optparse
import logging as logger
import datetime
from common.log_manage import LogManage
from common.utils import *
from common.catch_log import CatchLog

class CheckCrash(object):
    def __init__(self,device_sn,hdc_path,log_path):
        self.hdc_shell = "%s -t %s shell" % (hdc_path, device_sn)
        self.hdc_cmd = "%s -t %s" % (hdc_path, device_sn)
        self.log_list = set()
        self.log_path = log_path
        self.catch_log = CatchLog(log_path, device_sn, hdc_path)
        self.number = 0

    def check_crash_log(self):
        logger.info(" start check_crash_log")
        data_list = self.get_log_result()
        if len(data_list) == 0 :
            return
        temp_list = set(data_list).difference(self.log_list)
        if not temp_list :
            return
        temp_path = os.path.join(self.log_path,str(self.number))
        logger.info("temp_list = "+str(temp_list))
        for log_name in temp_list:
            logger.info("-------------temp_path : "+ temp_path + "-------- log_name :"+log_name)
            self.catch_log.get_cur_crash_log(temp_path,log_name.strip())
            self.log_list.add(log_name.strip())
        self.catch_log.get_cur_hilog_data(temp_path)
        self.catch_log.get_current_phone_status(temp_path)
        self.catch_log.get_hilog_buffer_data(temp_path)
        self.number +=1
        logger.info("end check_crash_log")
    def get_log_result(self):
        log_array = list()
        #native_crash_cmd = "%s ls /data/log/faultlog/temp" % self.hdc_shell
        js_crash_cmd = '%s "ls /data/log/faultlog/faultlogger | grep -E \'jscrash|cppcrash|appfreeze|sysfreeze\'"' % self.hdc_shell
        #native_log = exec_cmd(native_crash_cmd,wait_out=True)
        #native_log_array = list()
        #if native_log is not None and len(native_log) != 0:
            #native_log_array = native_log.strip().replace("\r","").split("\n")
        #for log_name in native_log_array:
            #if log_name.startswith("stacktrace"):
                #continue
            #log_array.append(log_name.strip())
        js_log_array = list()
        js_log = exec_cmd(js_crash_cmd,wait_out=True)
        if js_log is not None and len(js_log) != 0:
            js_log_array = js_log.strip().replace("\r","").split("\n")
        for js_name in js_log_array:
            log_array.append(js_name.strip())
        return log_array

    def filter_exception_data(self,log_result):
        temp_array = log_result.strip().replace("\r","").split("\n")
        logger.info("filter_exception_data = %s" % len(temp_array))
        log_array = filter(lambda name: "Not support std mode" not in name,temp_array)
        return list(log_array)
class RebootTest(object):

    REBOOT_LOOP = 600
    REBOOT_WAIT_TIME = 80
    REBOOT_MAX_WAIT_TIME = 300

    def __init__(self,device_sn,hdc_path,reboot_loop,log_path):
        self.device_sn = device_sn
        self.hdc_path = hdc_path
        self.reboot_loop = reboot_loop
        self.hdc_shell = "%s -t %s shell" % (hdc_path,device_sn)
        self.check_crash = CheckCrash(device_sn,hdc_path,log_path)
        self.ability_success = "start ability successfully"


    def execute_command(self,command):
        process = None
        try:
            process = subprocess.run(command,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,timeout=30)
        except subprocess.CalledProcessError as e:
            logger.info("execute_command exception = %s" % e)
        finally:
            result = process.stdout.decode().strip()
            return result


    def run(self):
        reboot_time = 0
        success_time = 1
        fail_time = 1
        start = datetime.now()
        check_command = "%s aa start -a com.ohos.photos.MainAbility -b com.ohos.photos" % self.hdc_shell
        while reboot_time <= self.reboot_loop:
            result = exec_cmd("%s list targets" % self.hdc_path,wait_out=True)
            logger.info("get devices list: " + str(result))
            if str(result).find(self.device_sn) != -1 :
                result = self.execute_command(check_command)
                logger.info("start photos result = %s" % result)
                if str(result).find(self.ability_success) != -1 :
                    logger.info("current loop is %d, total loop is %d" % (success_time,self.reboot_loop))
                    exec_cmd("%s reboot" % self.hdc_shell,wait_out=True)
                    success_time = success_time + 1
                    reboot_time = success_time + fail_time -1
                    start = datetime.now()
                    time.sleep(RebootTest.REBOOT_WAIT_TIME)
                    self.check_crash.check_crash_log()
                else:
                    logger.info("The device %s can not start APP after reboot." % self.device_sn)
                    logger.info("Reboot fail loop is %d, total loop is %d" % (fail_time,self.reboot_loop))
                    fail_time = fail_time +1
                    reboot_time = success_time + fail_time -1
            else:
                cur_time = datetime.now()
                if (cur_time - start).seconds > RebootTest.REBOOT_MAX_WAIT_TIME :
                    logger.info("The device %s is not ready after reboot for 300 seconds." % self.device_sn)
                    raise  ValueError("The device %s is not ready after reboot for 300 seconds." % self.device_sn)
                time.sleep(10)
        logger.info("Reboot success loop is %d,Reboot fail loop is %d,total loop is %d" % (success_time-1,fail_time-1,self.reboot_loop))
        logger.info("RebootTest Test End")

    def _wait_reboot(self,command):
        for index in range(3):
            time.sleep(10)
            result = self.execute_command(command)
            if str(result).find(self.ability_success) != -1 :
                return True
        logger.info("The device %s can not start APP after reboot \nThe test will stop." % self.device_sn)
        return False


def parse_option():
    parser = optparse.OptionParser()
    parser.add_option("-d","--devices",dest="devices",type="str",default=None,help='hdc list targets')
    parser.add_option("-p", "--hdc path", dest="hdc_path", type="str", default='hdc_std', help='hdc absolute path')
    parser.add_option("-c", "--count", dest="reboot_times", type="int", default=RebootTest.REBOOT_LOOP, help='hdc absolute path')
    ret_option,remainder = parser.parse_args()
    if ret_option.devices is None :
        raise ValueError(" please add -d argument (sn)")
    if ret_option.reboot_times <= 0:
        raise ValueError("please enter the correct argument -c " + str(ret_option.reboot_times))
    return ret_option
def main():
    option = parse_option()
    log_manage = LogManage(option.devices)
    pc_log_path = log_manage.get_log_dir(log_manage.get_reboot_dir_name())
    my_log = log_manage.init_logging(pc_log_path)
    set_env("%s -t %s shell" % (option.hdc_path,option.devices))
    press_test = RebootTest(option.devices,option.hdc_path,option.reboot_times,pc_log_path)
    press_test.run()
    my_log.clear_handlers()

if __name__ == '__main__':
    main()
